package com.vr.cloudpicture.aop;

import com.vr.cloudpicture.annotation.AuthCheck;
import com.vr.cloudpicture.enums.UserRoleEnum;
import com.vr.cloudpicture.exception.ErrorCode;
import com.vr.cloudpicture.exception.ThrowUtils;
import com.vr.cloudpicture.model.dto.user.UserLogin;
import com.vr.cloudpicture.service.IUserService;
import lombok.RequiredArgsConstructor;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

/**
 * 鉴权拦截器
 * @author hzh
 * @date 2025/04/28
 */
@Aspect
@Component
@RequiredArgsConstructor
public class AuthCheckInterceptor {
    private final IUserService userService;
    /**
     * 拦截@AuthCheck注解修饰的运行的方法，进行权限校验
     */
    @Around("@annotation(authCheck)")
    public Object doInterceptor(ProceedingJoinPoint joinPoint, AuthCheck authCheck) throws Throwable {
        // 获取注解里的mustRole属性
        String mustRole = authCheck.mustRole();
        // 获取当前请求中的HttpServletRequest类型的对象,来获取用户
        RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes();
        HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
        UserLogin loginUser = userService.getLoginUser(request);
        UserRoleEnum mustRoleMenu = UserRoleEnum.getEnumByValue(mustRole);
        if (mustRoleMenu==null) {
            // 表示没有设置权限,直接放行
            return joinPoint.proceed();
        }
        // 设置了权限
        // 获取当前用户的具有权限
        UserRoleEnum loginUserRoleMenu = UserRoleEnum.getEnumByValue(loginUser.getUserRole());
        // 表示当前登录的用户没有任何权限，或是非法权限
        ThrowUtils.throwIf(loginUserRoleMenu==null, ErrorCode.NOT_AUTH_ERROR);
        // 设置了管理员权限，但用户不是管理员权限，拒绝
        boolean condition=UserRoleEnum.ADMIN.equals(mustRoleMenu) && !UserRoleEnum.ADMIN.equals(loginUserRoleMenu);
        ThrowUtils.throwIf(condition, ErrorCode.NOT_AUTH_ERROR);
        // 否则放行
        return joinPoint.proceed();
    }
}
